Modern programming run-time environments, such a Java and the Microsoft .NET Common Language Runtime (CLR), offer an architecture for defining and enforcing access-control policies. The run-time environments have a list of predefined protected resources. Such a list can be extended by individual system administrators. Each protected resource is guarded by a permission at run time. When a protected resource is about to be accessed, a special component in the runtime, AccessController.checkPermission in Java and Demand in the CLR, is invoked. This component is the “access-control enforcer”. The access-control enforcer, when invoked on a particular resource, traverses the stack of execution and verifies that all the callers on the stack have been granted enough permissions to access the protected resource.
There is a major problem with this approach. The access-control policy is not properly enforced since the access-control enforcer only traverses the current stack of execution, demanding the principals, i.e., users or program components, on the stack exhibit the necessary permission. However, this stack traversal does not capture codes or subjects that have influenced the security-sensitive operation, for example, the name of a file being modified, unless those codes or subjects are still active on the stack. This may not be the case since code may have been popped out of its stack, but its influence may have been recorded in the heap or passed as a return value from a method that is no longer on the current stack of execution, and used for security-sensitive operations.
On the other hand, there are many systems where it is necessary to define and enforce information-flow integrity policies. In information-flow policies, the goal is to prevent untrusted principals from influencing trusted operations. A typical example of a system where integrity enforcement is essential is a Web application server. For Web applications, which constantly receive untrusted inputs from potentially untrusted users, it is very important to verify those inputs before using them in security-sensitive operations. There are two problems with these integrity policies. The first is that they are difficult to define, since a system administrator often does not know where the untrusted inputs come from and flow to. Second, they are difficult to enforce since proper enforcement requires detecting all the sources of influence and tracking those influences until a value is used.
Another difficulty is detecting implicit flows of information. In an implicit flow, an attacker does not directly modify or define the data that will be used in a security-sensitive operation. Rather, the attacker influences which data will be used.